4.3 Using the Batch API
For advanced scenarios requiring complex or
large batch jobs, such as inventory closing or data upgrades, the batch
server framework provides an X++ API that enables developers to create
or modify batch jobs, tasks, and their dependencies as needed as well as
to dynamically create run-time batch tasks on the fly. This flexible
API helps automate task creation and integrate batch processing into
other business processes. It can also be useful when your batch job or
task requires some additional logic.
Create a Batch Job
First, you have to create a Batch Job instance class named BatchHeader.
batchHeader = BatchHeader::construct();
|
Note
When you construct an instance of the BatchHeader class, no batch jobs are physically created in the system yet. All operations are performed in memory until you call the batchHeader.save function, which saves your changes in the database. |
You can also construct a BatchHeader object for an existing BatchJob by providing an optional batchJobId parameter to the construct method, as shown here.
batchHeader = BatchHeader::construct(this.parmCurrentBatch().BatchJobId);
|
The BatchHeader class allows you to access and modify most BatchJob parameters using parm methods. For example, you can set up recurrence and alerts for your batch job as shown in the following example.
// Set the batch recurrence
sysRecurrenceData = SysRecurrence::defaultRecurrence();
sysRecurrenceData = SysRecurrence::setRecurrenceStartDateTime(sysRecurrenceData,
DateTimeUtil::utcNow());
sysRecurrenceData = SysRecurrence::setRecurrenceNoEnd(sysRecurrenceData);
sysRecurrenceData = SysRecurrence::setRecurrenceUnit(sysRecurrenceData,
SysRecurrenceUnit::Hour, 1);
batchHeader.parmRecurrenceData(sysRecurrenceData);
// Set the batch alert configurations
batchHeader.parmAlerts(NoYes::No, NoYes::Yes, NoYes::No, NoYes::No, NoYes::No);
|
Add a Task to the Batch Job
After you create a batch job using the Batch API, you can add tasks to it by calling the addTask
method. The first parameter for this method is an instance of a
batch-enabled class that will be scheduled for execution as a batch
task.
void addTask(Batchable batchTask,
[BatchConstraintType constraintType])
|
Another way to create a task is to use the method addRuntimeTask,
which creates a dynamic batch task. It exists only for the current run,
and it gets copied into the history tables and deleted at the end of
the run. It copies settings such as batch group and child dependencies
from the inheritFromTaskId task.
void addRuntimeTask(Batchable batchTask,
RecId inheritFromTaskId,
[BatchConstraintType constraintType])
|
Define Dependencies Between Tasks
After you add tasks, you can use the Batch API to specify any dependencies between them. The BatchHeader class provides the method addDependency, which you can use to define a dependency between the tasks batchTaskToRun and dependsOnBatchTask.
The optional parameter batchStatus allows you to specify the type of the dependency. By default a dependency of type BatchDependencyStatus::Finished
is created, which means that the task starts execution only if the task
which it depends on finishes successfully. Other allowed options are BatchDependencyStatus::Error (the task will start execution if the preceding task finished with an error) and BatchDependencyStatus::FinishedOrError (the preceding task finished processing with any status result).
public BatchDependency addDependency(
Batchable batchTaskToRun,
Batchable dependsOnBatchTask,
[BatchDependencyStatus batchStatus])
|
Save a Batch Job
After you have finished defining the batch job, it’s important to call the batchHeader.save method. Under the hood, the save method inserts records into the BatchJob, Batch, and BatchConstraints
tables where the batch server can automatically pick them up for
execution. However, you must run client tasks manually by using the Set
Up Batch Processing form (from the Dynamics AX basic module, click
Periodic\Batch\Processing).
Example of a Batch Job
The following example shows how you can create a batch job and two batch tasks using the Batch API.
static void ExampleSchedulingJob (Args _args)
{
BatchHeader batchHeader;
RunBaseBatch batchTask;
;
// create batch header
batchHeader = BatchHeader::construct();
// create and add batch tasks
batchTask1 = new ExampleBatchTask();
batchTask1.parmCaption("Example batch job 1");
batchHeader.addTask(batchTask1);
batchTask2 = new ExampleBatchTask();
batchTask2.parmCaption("Example batch job 2");
batchHeader.addTask(batchTask2);
// add dependencies between batch tasks
batchHeader.addDependency(batchTask1, batchTask2);
// save batch job in the database
batchHeader.save();
} |